﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ISRecord.Model;
using System.Data;
using ISRecord.View.Properties;

namespace ISRecord.View.Services
{
    internal class ExcelData
    {
        const string OUTBOXNO = "OutboxNo";
        const string OUTBOXDATE = "OutboxDate";
        const string CUSTOMER = "Customer";
        const string PROPERTYNO = "PropertyNo";
        const string LOCATION = "Location";
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="sheetName"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="ReadingFromExcelException"/>
        /// <exception cref="InvalidOperationException"/>
        /// <exception cref="FormatException"/>


        public IEnumerable<Outbox> ReadFrom(string filePath, string sheetName)
        {
            DataSet ds = null;
            try
            {
                ds = ExcelService.GetExcelSheet(filePath, sheetName);
            }
            catch
            {
                throw;
            }
            if (ds == null) throw new InvalidOperationException(Resources.NoDataInExcelSheetMsg);
            if (TableMatchColumnsPattrenName(ds.Tables[0]))
            {
                int i = 0;
                foreach (DataRow row in ds.Tables[0].Rows)
                {

                    string outboxNo = PrefixOutboxNoWithCurrentYear(row[OUTBOXNO].ToString());
                    string outboxDate = DateValidation(row[OUTBOXDATE].ToString());
                    string subject = ConcatenateSubject(row, i);
                    string goingTo = row[CUSTOMER].ToString();
                    yield return new Outbox()
                    {
                        OutboxNo = outboxNo,
                        OutboxDate = outboxDate,
                        Subject = subject,
                        GoingTo = goingTo

                    };
                    i++;
                }
            }
            else
            {
               throw new FormatException(Resources.ExcelSheetColumnsNotMatchMsg);
            }

        }

        private string DateValidation(string dateString)
        {
            if( ! Helper.IsValidDate(dateString)) throw new FormatException(Resources.InvalidDateMsg);
            return dateString;
        }

        private string ConcatenateSubject(DataRow row, int rowno)
        {
            if (string.IsNullOrEmpty(row[PROPERTYNO].ToString()) ||
                string.IsNullOrEmpty(row[LOCATION].ToString()))
            { throw new FormatException(Resources.NoLocOrPropMsg); }

            string subject = "";

            if (!string.IsNullOrEmpty(Settings.Default.PrefixBeforSubject))
            {
                subject += string.Format("{0}{1}", Settings.Default.PrefixBeforSubject, " ");
            }
            subject += string.Format("{0} {1} {2}",
                                       row[PROPERTYNO].ToString(), " ", row[LOCATION].ToString());
            if (!string.IsNullOrEmpty(Settings.Default.PrefixAfterSubject))
            {
                subject += string.Format("{0}{1}", " ", Settings.Default.PrefixAfterSubject);
            }
            return subject;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="outboxNo"></param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"/>
        private string PrefixOutboxNoWithCurrentYear(string outboxNo)
        {
            string currentYear = Settings.Default.ActiveYear;
            if (string.IsNullOrEmpty(currentYear)) throw new InvalidOperationException(Resources.MissingActiveYearMsg);

            string prefixedOutbox = null;
            switch (outboxNo.Length)
            {
                case 1:
                    prefixedOutbox = string.Format("{0}{1}{2}", currentYear, "000", outboxNo);
                    break;
                case 2:
                    prefixedOutbox = string.Format("{0}{1}{2}", currentYear, "00", outboxNo);
                    break;
                case 3:
                    prefixedOutbox = string.Format("{0}{1}{2}", currentYear, "0", outboxNo);
                    break;
                case 4:
                    prefixedOutbox = string.Format("{0}{1}", currentYear, outboxNo);
                    break;
                default:
                    throw new InvalidOperationException(Resources.OutboxNoNotMatchedPattern);
            }
            return prefixedOutbox;
        }

        private bool TableMatchColumnsPattrenName(DataTable table)
        {
            bool res = false;

            DataColumnCollection columns = table.Columns;
            if (columns.Contains(OUTBOXNO) &&
                columns.Contains(OUTBOXDATE) &&
                columns.Contains(CUSTOMER) &&
                columns.Contains(PROPERTYNO) &&
                columns.Contains(LOCATION))
            {
                res = true;
            }
            return res;

        }
    }
}
